package org.particles.domain;

import java.util.ArrayList;
import java.util.List;

public class Vector2D implements Vector {
	private double x;
	private double y;
	
	public Vector2D() {
		super();
	}
	
	public Vector2D(final double x, final double y) {
		super();
		this.x = x;
		this.y = y;
	}
	
	public double getX() {
		return x;
	}
	
	public void setX(double x) {
		this.x = x;
	}
	
	public double getY() {
		return y;
	}
	
	public void setY(double y) {
		this.y = y;
	}
	
	@Override
	public List<Double> getCoordinate() {
		final List<Double> coordinate = new ArrayList<Double>(2);
		coordinate.add(x);
		coordinate.add(y);
		return coordinate;
	}
	
	/**
	 * @throws IndexOutOfBoundException if not enough values were passed into method.
	 * @throws NullPointerException if not enough values were passed into method.
	 */
	@Override
	public void setCoordinate(final double... coordinate) {
		x = coordinate[0];
		y = coordinate[1];
	}

	/**
	 * @throws IndexOutOfBoundException if not enough values were passed into method.
	 * @throws NullPointerException if not enough values were passed into method.
	 */
	@Override
	public void setCoordinate(final List<Double> coordinate) {
		x = coordinate.get(0);
		y = coordinate.get(1);
	}

	/**
	 * @throws IndexOutOfBoundException if passed vector is of a smaller dimension.
	 * @throws NullPointerException if vector is null.
	 */
	@Override
	public void copyStateFrom(final Vector vector) {
		setCoordinate(vector.getCoordinate());
	}

	@Override
	public void multiply(double scalar) {
		x *= scalar;
		y *= scalar;
	}

	/**
	 * @throws NullPointerException if vector is null.
	 * @throws ClassCastException if vector is not of type Vector2D.
	 */
	@Override
	public Vector addTo(final Vector vector) {
		final Vector2D v = (Vector2D) vector;
		return new Vector2D(x + v.getX(), y + v.getY());
	}

	/**
	 * @throws NullPointerException if vector is null.
	 * @throws ClassCastException if vector is not of type Vector2D.
	 */
	@Override
	public void add(Vector vector) {
		final Vector2D v = (Vector2D) vector;
		x += v.getX();
		y += v.getY();
	}

	@Override
	public Vector multiplyBy(double scalar) {
		return new Vector2D(x * scalar, y * scalar);
	}

	@Override
	public double length() {
		return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
	}

	/**
	 * @throws NullPointerException if vector is null.
	 * @throws ClassCastException if vector is not of type Vector2D.
	 */
	@Override
	public double distanceTo(Vector vector) {
		final Vector2D v = (Vector2D) vector;
		return Math.sqrt(Math.pow(x - v.getX(), 2) + Math.pow(y - v.getY(), 2));
	}

	@Override
	public void setLength(final double length) {
		final double scalar = length / this.length();
		this.multiply(scalar);
	}

	@Override
	public String toString() {
		return "[x = " + x + "; y = " + y + "]";
	}

	@Override
	public Vector subtractFrom(Vector vector) {
		final Vector2D v = (Vector2D) vector;
		return new Vector2D(v.getX() - x, v.getY() - y);
	}
	
	/**
	 * @throws NullPointerException if vector is null.
	 * @throws ClassCastException if vector is not of type Vector2D.
	 */
	@Override
	public void subtract(Vector vector) {
		final Vector2D v = (Vector2D) vector;
		x -= v.getX();
		y -= v.getY();
	}
	
}
